#include "Common.h"
#include "TimeLine/ShotCutTimeLine.h"
#include "ShotCutReaderWriter/ShotCutWriter.h"
#include "Application.h"
#include "ui_ShotCutPreviewVideo.h"

void ShotCutExportVideo::Run(int& argc, char** argv, string jsonPath)
{
    //加载json文件数据
    JsonSetting JsonData(jsonPath);

    //设置片段属性，裁剪拼接
	std::vector<ShotCutElement*> TimeLineElements;
	TimeLineVideoElement = new VideoElement(JsonData);
    TimeLineElements.push_back(TimeLineVideoElement);
    TimeLineElements.push_back(new AudioElement(JsonData, TimeLineVideoElement->JsonVideoData));
    TimeLineElements.push_back(new VideoEffectElement(JsonData, TimeLineVideoElement->JsonVideoData));
    TimeLineElements.push_back(new MaskEffectElement(JsonData, TimeLineVideoElement->JsonVideoData));
    TimeLineElements.push_back(new ImageEffectElement(JsonData, TimeLineVideoElement->JsonVideoData));
    TimeLineElements.push_back(new FontEffectElement(JsonData, TimeLineVideoElement->JsonVideoData));
    TimeLineElements.push_back(new CaptionElement(JsonData, TimeLineVideoElement->JsonVideoData));

    //把数据添加到timeline
    ShotCutTimeLine TimeLineOne(JsonData.TimeLineJsonData);
    for(ShotCutElement* Element : TimeLineElements)
    {
        Element->AttachToTimeLine(TimeLineOne);
    }

    //写入文件
    ShotCutWriter VideoWrite(&TimeLineOne);
    VideoWrite.RenderToFile(JsonData.WriteFileName);
	
	cout << "cycsgenerateddone" << endl;
}

ShotCutExportVideo::~ShotCutExportVideo()
{
	delete TimeLineVideoElement;
	TimeLineVideoElement = nullptr;
}

ShotCutPreviewVideo::ShotCutPreviewVideo(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::ShotCutPreviewVideo)
    , MoveRelativePos()
    , MoveSrcPos()
    , Video(new VideoRenderWidget(this))
    , Player(new QtPlayer(Video->GetRenderer()))
    , TimeLineVideoElement(nullptr)
	, PreviewTimeLine(nullptr)
	, Timer(new QTimer())
	, MaxFrame(0)
	, Fps(0)
{
    ui->setupUi(this);
    setWindowFlags(Qt::Window | Qt::FramelessWindowHint);
    setMouseTracking(true);

    ui->HorizontalLayout_Video->addWidget(Video);

    connect(Timer, &QTimer::timeout, this, &ShotCutPreviewVideo::UpdateSliderValue);
}

void ShotCutPreviewVideo::Reader(string jsonPath)
{
	//加载json文件数据
	JsonSetting JsonData(jsonPath);
	
	//设置片段属性，裁剪拼接
	std::vector<ShotCutElement*> TimeLineElements;
	TimeLineVideoElement = new VideoElement(JsonData);
	TimeLineElements.push_back(TimeLineVideoElement);
	TimeLineElements.push_back(new AudioElement(JsonData, TimeLineVideoElement->JsonVideoData));
	TimeLineElements.push_back(new VideoEffectElement(JsonData, TimeLineVideoElement->JsonVideoData));
	TimeLineElements.push_back(new MaskEffectElement(JsonData, TimeLineVideoElement->JsonVideoData));
	TimeLineElements.push_back(new ImageEffectElement(JsonData, TimeLineVideoElement->JsonVideoData));
	TimeLineElements.push_back(new FontEffectElement(JsonData, TimeLineVideoElement->JsonVideoData));
	TimeLineElements.push_back(new CaptionElement(JsonData, TimeLineVideoElement->JsonVideoData));
	
	//把数据添加到timeline
	PreviewTimeLine = new ShotCutTimeLine(JsonData.TimeLineJsonData);
	for(ShotCutElement* Element : TimeLineElements)
	{
		Element->AttachToTimeLine(*PreviewTimeLine);
	}
	
	if(PreviewTimeLine)
	{
		if(!PreviewTimeLine->VideoTimeLine->IsOpen())
		{
			PreviewTimeLine->VideoTimeLine->Open();
		}
		
		PreviewTimeLine->VideoTimeLine->SetMaxSize(640, 360);
		Player->Reader(PreviewTimeLine->VideoTimeLine.get());
		Video->SetAspectRatio(Player->Reader()->info.display_ratio, Player->Reader()->info.pixel_ratio);

		Fps = Player->Reader()->info.fps.ToInt();
        MaxFrame = PreviewTimeLine->VideoTimeLine->GetMaxFrame();
        ui->HorizontalSlider_Time->setRange(0, MaxFrame);
        ui->HorizontalSlider_Time->setSingleStep(1);
        ui->HorizontalSlider_Time->setPageStep(1);
        ui->Label_Frame->setNum(0);
        ui->Label_Time->setText(GetFrameString(0));
	}
	
	Player->Play();
    Player->Speed(0);
    Player->Pause();
}

ShotCutPreviewVideo::~ShotCutPreviewVideo()
{
	delete PreviewTimeLine;
	delete TimeLineVideoElement;
    delete ui;
	PreviewTimeLine = nullptr;
	TimeLineVideoElement = nullptr;
    ui = nullptr;
}

void ShotCutPreviewVideo::closeEvent(QCloseEvent *event)
{
    QWidget::hide();
    Player->Stop();
    QApplication::quit();
}

void ShotCutPreviewVideo::keyPressEvent(QKeyEvent *event)
{
    if (event->key() == Qt::Key_Space)
    {
        Play();
    }
    else if (event->key() == Qt::Key_Escape)
    {
        QWidget::hide();
        Player->Stop();
        QApplication::quit();
    }

    event->accept();
    QWidget::keyPressEvent(event);
}

void ShotCutPreviewVideo::Seek(int64_t SeekFrame)
{
	if (Player->Speed() != 0)
	{
		Player->Pause();
		Player->Speed(0);
	}
	
	Player->Seek(SeekFrame);
}

void ShotCutPreviewVideo::Play()
{
    if(Player->Position() >= MaxFrame)
    {
        ui->HorizontalSlider_Time->setValue(1);
    }
	
    if (Player->Mode() == PLAYBACK_PAUSED)
    {
        Timer->start(100);
        Player->Play();
    }
    else if (Player->Mode() == PLAYBACK_PLAY)
    {
        if (Player->Speed() == 0)
        {
            Player->Speed(1);
        }
        else
        {
            Timer->stop();
            Player->Pause();
        }
    }
}

QString ShotCutPreviewVideo::GetFrameString(int64 FrameNumb)
{
	int Second = FrameNumb / Fps;
    return QString::number(Second / 60) + ":" + QString::number(Second % 60);
}

void ShotCutPreviewVideo::on_Button_Play_clicked()
{
    if(Player->Position() >= MaxFrame)
    {
        ui->HorizontalSlider_Time->setValue(1);
    }

    Player->Speed(1);
    Timer->start(100);
    Player->Play();
}

void ShotCutPreviewVideo::on_Button_Stop_clicked()
{
    Player->Speed(0);
    Timer->stop();
    Player->Pause();
}

void ShotCutPreviewVideo::on_HorizontalSlider_Time_valueChanged(int value)
{
    ui->Label_Frame->setNum(value);
    ui->Label_Time->setText(GetFrameString(value));
    Seek(value);
}

void ShotCutPreviewVideo::UpdateSliderValue()
{
	int CurrentFrame = Player->Position();

	if(CurrentFrame >= MaxFrame)
	{
		Timer->stop();
	}
    ui->Label_Frame->setNum(CurrentFrame);
    ui->Label_Time->setText(GetFrameString(CurrentFrame));
    ui->HorizontalSlider_Time->blockSignals(true);
    ui->HorizontalSlider_Time->setValue(CurrentFrame);
    ui->HorizontalSlider_Time->blockSignals(false);
}

void ShotCutPreviewVideo::mousePressEvent(QMouseEvent *event)
{
    if(event->button() == Qt::LeftButton)
    {
        MoveSrcPos = event->globalPos();
        MoveRelativePos = event->globalPos() - frameGeometry().topLeft();
    }
    event->accept();
    QWidget::mousePressEvent(event);
}

void ShotCutPreviewVideo::mouseMoveEvent(QMouseEvent *event)
{
    if(!(QWidget::isMaximized() || QWidget::isMinimized()))
    {
        int dx = 0, dy = 0;

        if(ui->Label_Title->underMouse())
        {
            move(event->globalPos() - MoveRelativePos);
        }
        else if(ui->Line_Right->underMouse())
        {
            dx = event->globalPos().x() - MoveSrcPos.x();
            resize(width() + dx, height());
        }
        else if(ui->Line_Left->underMouse())
        {
            dx = event->globalPos().x() - MoveSrcPos.x();
            resize(width() - dx, height());
            move(MoveSrcPos.x(), (MoveSrcPos - MoveRelativePos).y());
        }
        else if(ui->Line_Buttom->underMouse())
        {
            dy = event->globalPos().y() - MoveSrcPos.y();
            resize(width(), height() + dy);
        }

        MoveSrcPos = MoveSrcPos + QPoint(dx, dy);
    }
    event->accept();
    QWidget::mouseMoveEvent(event);
}

void ShotCutPreviewVideo::on_Button_Close_clicked()
{
    QWidget::hide();
    QApplication::quit();
}


void ShotCutPreviewVideo::on_Button_Maximize_clicked()
{
    if(QWidget::isMaximized())
    {
        ui->Button_Maximize->setStyleSheet("image: url(:/Resource/Image/FullScreen.PNG);");
        QWidget::showNormal();
    }
    else
    {
        ui->Button_Maximize->setStyleSheet("image: url(:/Resource/Image/Window.PNG);");
        QWidget::showMaximized();
    }
}

void ShotCutPreviewVideo::on_Button_Minimize_clicked()
{
    QWidget::showMinimized();
}

